package org.jeecg.modules.vo;

import lombok.Data;

import org.jeecg.modules.enmu.MessageTypeEnum;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

@Data
public class TcpLoginRequest {
    private static final int FIXED_HEADER = 0x7E7C6B5A;
    private static final int MESSAGE_TYPE_LOGIN = MessageTypeEnum.LOGIN.getValue();
    private static final int MESSAGE_SEQ = 1; // 消息序号定义为int类型
    private static final int USERNAME_LENGTH = 20;
    private static final int PASSWORD_LENGTH = 20;
    private  String username;
    private  String password;

    private String newPassword;
    /**
     * 0 一问一答，1改变时自动发送，2定时发送，3停止发送
     */
    private String way;

    /**
     * 定时时间间隔
     * @return
     */
    private int PollingTime;

    /*
    需要查询数据的iDs
     */
    private String []  dataIds;

    private String dataId;

    /**
     * 请求告警等级
     * @return
     */
    private String mode;






    public byte[] toBytes() {
        // 计算消息体长度
        int bodyLength = USERNAME_LENGTH + PASSWORD_LENGTH;

        // 计算总消息长度（包括固定报文头、消息长度、消息类型、消息序号和消息体）
        int messageLength = 4 + 4 + 4 + 4 + bodyLength; // 固定报文头 + 消息长度 + 消息类型 + 消息序号 + 消息体长度

        // 创建ByteBuffer
        ByteBuffer buffer = ByteBuffer.allocate(messageLength);

        // 写入固定报文头
        buffer.putInt(FIXED_HEADER);

        // 写入消息长度
        buffer.putInt(messageLength);

        // 写入消息类型
        buffer.putInt(MESSAGE_TYPE_LOGIN);

        // 写入消息序号
        buffer.putInt(MESSAGE_SEQ);

        // 写入用户名，不足20字节的部分用空格填充
        byte[] usernameBytes = padWithSpaces(username, USERNAME_LENGTH).getBytes(StandardCharsets.UTF_8);
        buffer.put(usernameBytes);

        // 写入密码，不足20字节的部分用空格填充
        byte[] passwordBytes = padWithSpaces(password, PASSWORD_LENGTH).getBytes(StandardCharsets.UTF_8);

        buffer.put(passwordBytes);
        byte[] data = buffer.array();
        int crc16Value = calculateCRC16(data, 0, data.length - 2);
        buffer.putShort((short) crc16Value);
        // 返回字节数组
        return buffer.array();
    }

    private static String padWithSpaces(String original, int length) {
        if (original.length() >= length) {
            return original.substring(0, length);
        }
        return String.format("%-" + length + "s", original);
    }


    private static int calculateCRC16(byte[] data, int offset, int length) {
        int crc = 0xFFFF;
        for (int i = offset; i < offset + length; i++) {
            crc ^= (short) (data[i] & 0xFF);
            for (int j = 0; j < 8; j++) {
                if ((crc & 1) == 1) {
                    crc = (short) ((crc >>> 1) ^ 0xA001);
                } else {
                    crc >>>= 1;
                }
            }
        }
        return crc;
    }

    public static void main(String[] args) {
        TcpLoginRequest loginRequest = new TcpLoginRequest();
        loginRequest.setUsername("ParentSC");
        loginRequest.setPassword("123456");
        byte[] bytes = loginRequest.toBytes();
        System.out.println("TCP login request bytes: " + bytesToHex(bytes));
    }


    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02X ", b));
        }
        return result.toString();
    }
}